#!/bin/bash -eu
#
# Copyright 2020 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#######################################
# Creates a user for Mattermost application in MYSQL database.
# Arguments:
#   MySQL Hostname.
#   MySQL Database Name.
#   MySQL Username to be created.
#   MySQL Password for username created.
#######################################
function create_db_user() {
  local db_host="$1"
  local db_name="$2"
  local db_user="$3"
  local db_pwd="$4"

  echo >&2 "Creating database user..."
  mysql -u root -e "CREATE USER '${db_user}'@'${db_host}' IDENTIFIED BY '${db_pwd}';"
  mysql -u root -e "GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES ON ${db_name}.* TO '${db_user}'@'${db_host}' IDENTIFIED BY '${db_pwd}';";
  mysql -u root -e "FLUSH PRIVILEGES"
}

#######################################
# Updates Mattermost configuration
# Arguments:
#   Data Source Name for connection between Mattermost and MySQL
#   Mattermost Website Name
#######################################
function update_config() {
  local -r dsn="$1"
  local -r site_name="$2"
  local -r driver="mysql"
  local config_path=/opt/mattermost/config/config.json

  echo >&2 "Updating Mattermost configuration..."
  local config_contents="$(jq -r \
    --arg driver "${driver}" \
    --arg dsn "${dsn}" \
    --arg site_name "${site_name}"  \
    '.TeamSettings.SiteName = $site_name
      | .SqlSettings.DriverName = $driver
      | .SqlSettings.DataSource = $dsn' "${config_path}")"

  echo "${config_contents}" > "${config_path}"
}

#######################################
# Generate a certificate using Let's Encrypt
# Arguments:
#   Domain name for the certificate
#   Email to be registered in Let's Encrypt
#######################################
function generate_certificate() {
  local -r domain_name="$1"
  local -r email="$2"

  echo >&2 "Generating certificate..."
  /opt/certbot/letsencrypt-auto certonly \
    -d "${domain_name}" \
    --standalone \
    --non-interactive \
    --agree-tos \
    --email "${email}" \
    --verbose
}

#######################################
# Set nginx configurations for https ot http
# Arguments:
#   Domain name for the certificate
#   Email to be registered in Let's Encrypt
#######################################
function setup_nginx() {
  export DOMAIN_NAME="$1"
  local email="${2:-""}"
  local -r nginx_config="/etc/nginx/sites-available/mattermost"

  # If a domain name is provided, generate certificate and configure
  # HTTPS for nginx. Otherwise, applies all hosts with HTTP configuration.
  if [[ "${DOMAIN_NAME}" == "" ]] || [[ "${DOMAIN_NAME}" == "localhost" ]]; then
    echo >&2 "Configuring nginx with localhost strategy..."
    # Copy template for all hosts configuration with HTTP
    cp -f /opt/mattermost-nginx-localhost.conf "${nginx_config}"
  else
    echo >&2 "Configuring nginx with a domain strategy for ${DOMAIN_NAME}..."
    echo >&2 "Stopping nginx..."
    systemctl stop nginx

    echo >&2 "Generating certificate..."
    generate_certificate "${DOMAIN_NAME}" "${email}"

    # Applying domain name to template for HTTPS configuration with domain name
    envsubst "\$DOMAIN_NAME" < /opt/mattermost-nginx-domain.conf > "${nginx_config}"
  fi

  # Applies mattermost nginx config
  rm -f /etc/nginx/sites-enabled/default
  ln -sf "${nginx_config}" /etc/nginx/sites-enabled/mattermost

  echo >&2 "Restarting nginx..."
  # Restart nginx configuration
  systemctl restart nginx
}

#######################################
# Await the application to be ready.
#######################################
function wait_for_app() {
  local max_retries=10
  local retry=1
  local http_code=0

  while [[ "${http_code}" -ne 200 && "${retry}" -le "${max_retries}" ]]; do
    http_code="$(curl -s -L -o /dev/null -w "%{http_code}" http://localhost)"
    (( retry=retry+1 ))
    sleep 5
  done

  if [[ "${retry}" -gt "${max_retries}" ]]; then
    echo "Max retries exceeded."
    exit 1
  fi
}
